"""
房间服务层
"""
from models import Room, RoomType, RoomStatus, Reservation
from extension import db
from datetime import datetime
from sqlalchemy.orm import joinedload
from mappers.room_mapper import RoomMapper
from .base_service import BaseService


class RoomService(BaseService):
    """房间业务逻辑"""
    
    def __init__(self):
        super().__init__(Room)
        self.mapper = RoomMapper()
    
    def get_rooms_with_filters(self, page=1, per_page=10, search=None, room_type_id=None, room_status_id=None):
        """获取房间列表（支持多条件过滤）"""
        query = Room.query.options(
            joinedload(Room.room_type),
            joinedload(Room.room_status)
        )
        
        if search:
            query = query.filter(Room.room_number.like(f'%{search}%'))
        if room_type_id:
            query = query.filter(Room.room_type_id == room_type_id)
        if room_status_id:
            query = query.filter(Room.room_status_id == room_status_id)
        
        query = query.order_by(Room.room_number.asc())
        return query.paginate(page=page, per_page=per_page, error_out=False)
    
    def get_room_detail(self, room_id):
        """获取房间详情"""
        return Room.query.options(
            joinedload(Room.room_type),
            joinedload(Room.room_status)
        ).get(room_id)
    
    def create_room(self, room_number, floor, room_type_id, area=None, bed_type=None, 
                   max_guests=2, room_status_id=1, description=None):
        """创建房间"""
        # 检查房间号是否已存在
        if Room.query.filter_by(room_number=room_number).first():
            raise ValueError('房间号已存在')
        
        # 检查房间类型是否存在
        if not RoomType.query.get(room_type_id):
            raise ValueError('房间类型不存在')
        
        room = Room(
            room_number=room_number,
            floor=floor,
            room_type_id=room_type_id,
            area=area,
            bed_type=bed_type,
            max_guests=max_guests,
            room_status_id=room_status_id,
            description=description or ''
        )
        db.session.add(room)
        db.session.commit()
        return room
    
    def update_room(self, room_id, **data):
        """更新房间信息"""
        room = self.get_room_detail(room_id)
        if not room:
            return None
        
        # 检查房间号是否重复
        if 'room_number' in data and data['room_number'] != room.room_number:
            if Room.query.filter(Room.room_number == data['room_number']).first():
                raise ValueError('新房间号已存在')
        
        for key, value in data.items():
            if hasattr(room, key) and value is not None:
                setattr(room, key, value)
        
        db.session.commit()
        return room
    
    def delete_room(self, room_id):
        """删除房间（检查是否有关联预订）"""
        room = self.get_by_id(room_id)
        if not room:
            return False
        
        # 检查是否存在关联的预订记录
        if Reservation.query.filter_by(room_id=room_id).first():
            raise ValueError('该房间存在关联的预订记录，无法删除')
        
        db.session.delete(room)
        db.session.commit()
        return True
    
    def get_room_types(self):
        """获取所有房间类型"""
        return RoomType.query.all()
    
    def get_room_statuses(self):
        """获取所有房间状态"""
        return RoomStatus.query.all()
    
    def check_room_availability(self, room_id, check_in, check_out):
        """检查房间在指定时间段是否可用"""
        room = self.get_by_id(room_id)
        if not room:
            return False
        
        # 检查是否有冲突的预订
        conflicting = Reservation.query.filter(
            Reservation.room_id == room_id,
            Reservation.status != 4,  # 排除已取消的预订
            Reservation.check_in < check_out,
            Reservation.check_out > check_in
        ).first()
        
        return conflicting is None
    
    def check_availability(self, room_id, check_in, check_out):
        """检查房间可用性（别名方法）"""
        return self.check_room_availability(room_id, check_in, check_out)
    
    def get_available_rooms(self, page=1, per_page=10, room_type_id=None, check_in=None, check_out=None):
        """获取可用房间列表"""
        query = Room.query.options(
            joinedload(Room.room_type),
            joinedload(Room.room_status)
        )
        
        # 只获取状态为"可用"的房间
        query = query.filter(Room.room_status_id == 1)
        
        if room_type_id:
            query = query.filter(Room.room_type_id == room_type_id)
        
        # 如果提供了入住和退房日期，检查时间段内的可用性
        if check_in and check_out:
            # 获取在该时间段有预订的房间ID
            booked_rooms = db.session.query(Reservation.room_id).filter(
                Reservation.status != 4,  # 排除已取消的预订
                Reservation.check_in < check_out,
                Reservation.check_out > check_in
            ).all()
            booked_room_ids = [room_id[0] for room_id in booked_rooms]
            
            # 排除已预订的房间
            if booked_room_ids:
                query = query.filter(Room.id.notin_(booked_room_ids))
        
        query = query.order_by(Room.room_number.asc())
        return query.paginate(page=page, per_page=per_page, error_out=False)
    
    def get_available_rooms_dto(self, page=1, per_page=10, room_type_id=None, check_in=None, check_out=None):
        """获取可用房间列表（返回DTO）"""
        paginated = self.get_available_rooms(page, per_page, room_type_id, check_in, check_out)
        return {
            'list': [self._format_room_for_user(room) for room in paginated.items],
            'total': paginated.total,
            'page': paginated.page,
            'pageSize': paginated.per_page,
            'pages': paginated.pages
        }
    
    def get_room_detail_dto(self, room_id):
        """获取房间详情（用户端，返回DTO）"""
        room = self.get_by_id(room_id)
        return self._format_room_for_user(room) if room else None
    
    def _format_room_for_user(self, room):
        """格式化房间数据（用户端）"""
        return {
            'id': room.id,
            'roomNumber': room.room_number,
            'floor': room.floor,
            'roomTypeId': room.room_type_id,
            'roomType': room.room_type.name if room.room_type else None,
            'roomStatusId': room.room_status_id,
            'roomStatus': room.room_status.name if room.room_status else None,
            'area': float(room.area) if room.area else 0,
            'maxGuests': room.max_guests,
            'bedType': room.bed_type,
            'description': room.description,
            'price': float(room.room_type.price) if room.room_type else 0,
            'image': room.room_type.image if room.room_type else None
        }
    
    def get_room_statistics(self):
        """获取房间统计信息"""
        total_rooms = Room.query.count()
        occupied_rooms = Room.query.filter_by(room_status_id=2).count()  # 假设2为已占用
        available_rooms = Room.query.filter_by(room_status_id=1).count()  # 假设1为可用
        
        return {
            'total': total_rooms,
            'occupied': occupied_rooms,
            'available': available_rooms,
            'occupancy_rate': (occupied_rooms / total_rooms * 100) if total_rooms > 0 else 0
        }
    
    def get_rooms_paginated_dto(self, page=1, per_page=10, search=None, room_type_id=None, room_status_id=None):
        """获取房间列表（返回DTO）"""
        paginated = self.get_rooms_with_filters(page, per_page, search, room_type_id, room_status_id)
        return {
            'list': [self.mapper.to_dict(room) for room in paginated.items],
            'total': paginated.total,
            'page': paginated.page,
            'pageSize': paginated.per_page,
            'pages': paginated.pages
        }
    
    def get_room_dto(self, room_id):
        """获取房间详情（返回DTO）"""
        room = self.get_room_detail(room_id)
        return self.mapper.to_dict(room) if room else None
    
    def create_room_dto(self, room_number, floor, room_type_id, area=None, bed_type=None, 
                       max_guests=2, room_status_id=1, description=None):
        """创建房间（返回DTO）"""
        room = self.create_room(room_number, floor, room_type_id, area, bed_type, max_guests, room_status_id, description)
        return self.mapper.to_dict(room)
    
    def update_room_dto(self, room_id, **data):
        """更新房间（返回DTO）"""
        room = self.update_room(room_id, **data)
        return self.mapper.to_dict(room) if room else None
